package com.emperor.product.app;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.hibernate.Session;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.Restrictions;

import com.emperor.category.logic.Category;
import com.emperor.category.logic.CategoryModel;
import com.emperor.core.app.App;
import com.emperor.core.app.AppBase;
import com.emperor.core.app.AppConstant;
import com.emperor.inventory.app.InventoryAppCtrl;
import com.emperor.product.logic.Product;
import com.emperor.product.logic.ProductModel;
import com.emperor.productlog.logic.ProductLog;
import com.emperor.productlog.logic.ProductLogModel;
import com.emperor.util.HibernateUtil;
import com.swtdesigner.SWTResourceManager;

public class ProductAppMgm extends AppBase implements App {

	private Label categoryLabel_3_4;
	private Label categoryLabel_3_3;
	private Label categoryLabel_3_2;
	private Text text_12;
	private Text text_11;
	private Text text_10;
	private Button resetButton;
	private Button updateButton;
	private Combo combo_2;
	private Text text_9;
	private Text text_8;
	private Text text_7;
	private Combo combo;
	private Text text_6;
	private Text text_5;
	private Text text_4;
	private Text text_3;
	private Text text_2;
	private Text text;
	protected Shell shell;

	public static Logger log = Logger.getLogger(ProductAppMgm.class);

	public ProductAppMgm() {
		super();
	}

	public ProductAppMgm(Map<String, Object> params) {
		super();
		this.params = params;
	}

	/**
	 * Launch the application
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			ProductAppMgm window = new ProductAppMgm();
			window.open();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Open the window
	 */
	public void open() {
		final Display display = Display.getDefault();
		createContents();
		shell.open();
		shell.layout();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
	}

	/**
	 * Create contents of the window
	 */
	protected void createContents() {
		shell = new Shell();
		shell.setBackgroundImage(SWTResourceManager.getImage(
				ProductAppMgm.class, "/img/main.jpg"));
		shell.setImage(SWTResourceManager.getImage(ProductAppMgm.class,
				"/img/iMac OSX.png"));
		shell.setBackgroundMode(SWT.INHERIT_DEFAULT);
		shell.setFont(SWTResourceManager.getFont("", 12, SWT.NONE));
		shell.setSize(1280, 800);
		shell.setText("Update Product");

		initScreen(shell, getParams());
		//
		buildStandardMenu(getShell(), getParams(),
				InventoryAppCtrl.INVENTORY_CTRL, InventoryAppCtrl.INVENTORY_ENQ);

		final Composite composite = new Composite(shell, SWT.NONE);
		composite.setBounds(0, 50, 1272, 636);

		final Label messageLabel = new Label(composite, SWT.NONE);
		messageLabel.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));
		messageLabel
				.setText("Please update the Product Detail and click Update button to save the changes.");
		messageLabel.setBounds(10, 0, 578, 20);

		text = new Text(composite, SWT.BORDER);
		text.setToolTipText("prod_name");
		text.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI",
				12, SWT.NORMAL));
		text.setBounds(185, 70, 403, 30);

		text_2 = new Text(composite, SWT.BORDER);
		text_2.setToolTipText("prod_sku");
		text_2.setBounds(185, 106, 403, 30);
		text_2.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));

		text_3 = new Text(composite, SWT.BORDER);
		text_3.setToolTipText("prod_price");
		text_3.setBounds(185, 248, 203, 30);
		text_3.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));

		text_4 = new Text(composite, SWT.BORDER);
		text_4.setToolTipText("prod_discount");
		text_4.setBounds(185, 284, 203, 30);
		text_4.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));

		text_5 = new Text(composite, SWT.BORDER);
		text_5.setToolTipText("prod_quantity");
		text_5.setBounds(185, 320, 203, 30);
		text_5.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));

		text_6 = new Text(composite, SWT.V_SCROLL | SWT.MULTI | SWT.BORDER);
		text_6.setToolTipText("prod_desc");
		text_6.setBounds(185, 356, 403, 151);
		text_6.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));

		combo = new Combo(composite, SWT.NONE);
		combo.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI",
				12, SWT.NORMAL));
		combo.setBounds(185, 36, 403, 28);

		text_7 = new Text(composite, SWT.BORDER);
		text_7.setVisible(false);
		text_7.setBounds(779, 188, 203, 30);
		text_7.setToolTipText("prod_id");
		text_7.setFont(SWTResourceManager.getFont("", 12, SWT.NONE));

		text_8 = new Text(composite, SWT.BORDER);
		text_8.setVisible(false);
		text_8.setBounds(779, 224, 203, 30);
		text_8.setToolTipText("prod_status");
		text_8.setFont(SWTResourceManager.getFont("", 12, SWT.NONE));

		updateButton = new Button(composite, SWT.NONE);
		updateButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent e) {
				try {
					Product product = new ProductModel();

					Session session = HibernateUtil.getSessionFactory()
							.getCurrentSession();
					session.beginTransaction();

					product = (Product) setModel(composite, "prod", product);
					product = (Product) session.get(ProductModel.class,
							product.getId());

					Double xquantity = product.getQuantity();

					product = (Product) setModel(composite, "prod", product);
					ProductAppMgmRmk dialog = null;
					if (product.getQuantity().doubleValue() > xquantity
							.doubleValue()) {
						dialog = new ProductAppMgmRmk(getShell(),
								SWT.ICON_INFORMATION, getParams(), true);
					} else if (product.getQuantity().doubleValue() < xquantity
							.doubleValue()) {
						dialog = new ProductAppMgmRmk(getShell(),
								SWT.ICON_INFORMATION, getParams(), false);
					}
					if (dialog != null) {
						dialog.open();
					}

					log.debug(product.getClass().getSimpleName() + " : "
							+ product.getValues().toString());

					List<String> errors = ProductAppNew.validateForm(product);
					if (errors.isEmpty()) {
						product = (Product) preUpdate(product, getParams());
						Category category = null;

						if (combo.getText().length() > 0) {
							List<Category> categories = session
									.createCriteria(CategoryModel.class)
									.add(Expression.eq(Category.FLD_NAME,
											combo.getText()))
									.add(Expression.eq(Category.FLD_STATUS,
											AppConstant.STATUS_ACTIVE)).list();
							if (categories != null && !categories.isEmpty()) {
								category = categories.get(0);
							}

							if (category != null && category.getId() != null) {
								product.setCategory(category);
							}
						}

						int rowCount = doUpdate(product);
						if (rowCount == 1) {
							if (getParams().get(
									ProductAppCtrl.PRODUCT_ACTIONNAME) != null) {
								ProductAppNew
										.logProduct(
												product,
												getParams(),
												getParams()
														.get(ProductAppCtrl.PRODUCT_ACTIONNAME)
														.toString(), null,
												xquantity);
							} else {
								ProductAppNew.logProduct(product, getParams(),
										ProductLog.ACT_UPDATE, null, xquantity);
							}

							message(getShell(), "Update Success.",
									"Product updated successfully.");

							getParams().put(AppConstant.APPCTRL,
									InventoryAppCtrl.INVENTORY_CTRL);
							getParams().put(AppConstant.ACTION,
									InventoryAppCtrl.INVENTORY_ENQ);
							getShell().close();
						}
					} else {
						message(getShell(), "Update Error.", errors,
								SWT.ICON_ERROR | SWT.OK);
					}
				} catch (Exception ex) {
					message(getShell(), "Update Error.", ex.getMessage(),
							SWT.ICON_ERROR | SWT.OK);
					log.error("Unable to update product.", ex);
				}
			}
		});
		updateButton.setImage(SWTResourceManager.getImage(ProductAppMgm.class,
				"/img/Edit.png"));
		updateButton.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));
		updateButton.setText("Update");
		updateButton.setBounds(185, 513, 90, 30);

		resetButton = new Button(composite, SWT.NONE);
		resetButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent e) {
				getShell().close();
			}
		});
		resetButton.setImage(SWTResourceManager.getImage(ProductAppMgm.class,
				"/img/Refresh.png"));
		resetButton.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));
		resetButton.setText("Reset");
		resetButton.setBounds(281, 513, 80, 30);

		final Label categoryLabel = new Label(composite, SWT.NONE);
		categoryLabel.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));
		categoryLabel.setText("Category");
		categoryLabel.setBounds(10, 39, 65, 20);

		final Label categoryLabel_1 = new Label(composite, SWT.NONE);
		categoryLabel_1.setBounds(10, 73, 65, 20);
		categoryLabel_1.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));
		categoryLabel_1.setText("Name");

		final Label categoryLabel_2 = new Label(composite, SWT.NONE);
		categoryLabel_2.setBounds(10, 109, 65, 20);
		categoryLabel_2.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));
		categoryLabel_2.setText("SKU");

		final Label categoryLabel_3 = new Label(composite, SWT.NONE);
		categoryLabel_3.setBounds(10, 251, 65, 20);
		categoryLabel_3.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));
		categoryLabel_3.setText("Price");

		final Label categoryLabel_4 = new Label(composite, SWT.NONE);
		categoryLabel_4.setBounds(10, 287, 65, 20);
		categoryLabel_4.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));
		categoryLabel_4.setText("Discount");

		final Label categoryLabel_5 = new Label(composite, SWT.NONE);
		categoryLabel_5.setBounds(10, 323, 65, 20);
		categoryLabel_5.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));
		categoryLabel_5.setText("Quantity");

		final Label categoryLabel_6 = new Label(composite, SWT.NONE);
		categoryLabel_6.setBounds(10, 359, 80, 20);
		categoryLabel_6.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));
		categoryLabel_6.setText("Description");
		final Label categoryLabel_3_1 = new Label(composite, SWT.NONE);
		categoryLabel_3_1.setVisible(false);
		categoryLabel_3_1.setBounds(603, 283, 65, 20);
		categoryLabel_3_1.setFont(SWTResourceManager.getFont("", 12, SWT.NONE));
		categoryLabel_3_1.setText("Weight");

		text_9 = new Text(composite, SWT.BORDER);
		text_9.setVisible(false);
		text_9.setBounds(778, 280, 203, 30);
		text_9.setToolTipText("prod_weight");
		text_9.setFont(SWTResourceManager.getFont("", 12, SWT.NONE));

		combo_2 = new Combo(composite, SWT.NONE);
		combo_2.setVisible(false);
		combo_2.setVisibleItemCount(6);
		combo_2.setBounds(998, 280, 95, 28);
		combo_2.setToolTipText("prod_weightuom");
		combo_2.select(0);
		combo_2.setFont(SWTResourceManager.getFont("", 12, SWT.NONE));
		combo_2.add(Product.UOM_ML);
		combo_2.add(Product.UOM_L);
		combo_2.add(Product.UOM_GM);
		combo_2.add(Product.UOM_KG);
		combo_2.select(0);

		text_10 = new Text(composite, SWT.BORDER);
		text_10.setBounds(185, 142, 203, 30);
		text_10.setToolTipText("prod_color");
		text_10.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));

		text_11 = new Text(composite, SWT.BORDER);
		text_11.setBounds(185, 178, 203, 30);
		text_11.setToolTipText("prod_invoiceno");
		text_11.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));

		text_12 = new Text(composite, SWT.BORDER);
		text_12.setBounds(185, 212, 203, 30);
		text_12.setToolTipText("prod_cost");
		text_12.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));

		categoryLabel_3_2 = new Label(composite, SWT.NONE);
		categoryLabel_3_2.setBounds(10, 145, 65, 20);
		categoryLabel_3_2.setFont(org.eclipse.wb.swt.SWTResourceManager
				.getFont("Segoe UI", 12, SWT.NORMAL));
		categoryLabel_3_2.setText("Color");

		categoryLabel_3_3 = new Label(composite, SWT.NONE);
		categoryLabel_3_3.setBounds(10, 181, 75, 20);
		categoryLabel_3_3.setFont(org.eclipse.wb.swt.SWTResourceManager
				.getFont("Segoe UI", 12, SWT.NORMAL));
		categoryLabel_3_3.setText("Invoice No");

		categoryLabel_3_4 = new Label(composite, SWT.NONE);
		categoryLabel_3_4.setBounds(10, 215, 65, 20);
		categoryLabel_3_4.setFont(org.eclipse.wb.swt.SWTResourceManager
				.getFont("Segoe UI", 12, SWT.NORMAL));
		categoryLabel_3_4.setText("Cost");
		//
		populateControls(composite, combo);

		composite.setTabList(new Control[] { combo, text, text_2, text_10,
				text_11, text_12, text_3, text_4, text_5, text_6, text_7,
				text_8, updateButton, resetButton });

	}

	private void populateControls(Composite composite, Combo combo) {
		if (getParams().get(ProductAppCtrl.PRODUCT_ID) == null) {
			getParams().put(InventoryAppCtrl.INVENTORY_MSG,
					"Unable to display product. Product ID not found.");

			getParams().put(AppConstant.APPCTRL,
					InventoryAppCtrl.INVENTORY_CTRL);
			getParams().put(AppConstant.ACTION, InventoryAppCtrl.INVENTORY_ENQ);
			getShell().close();
		}

		try {
			Long id = (Long) getParams().get(ProductAppCtrl.PRODUCT_ID);

			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.beginTransaction();

			Product product = (Product) session.get(ProductModel.class, id);

			if (product != null && product.getId() != null) {
				setControls(composite, "prod", product);

				List<Category> categories = session
						.createCriteria(CategoryModel.class)
						.add(Restrictions.eq(Category.FLD_TYPE,
								Category.TYPE_PRODUCT))
						.add(Expression.eq(Category.FLD_STATUS,
								AppConstant.STATUS_ACTIVE)).list();

				int index = 0;
				for (Iterator<Category> iter = categories.iterator(); iter
						.hasNext();) {
					Category category = iter.next();

					combo.add(category.getName());
					if (product.getCategory().getName()
							.equals(category.getName())) {
						combo.select(index);
					}
					index++;
				}
			}
		} catch (Exception e) {
			log.error("Unable to populate control.", e);
		}
	}

	private int doUpdate(Product product) throws Exception {
		int rowCount = 0;
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		try {
			session.beginTransaction();
			rowCount++;

			session.saveOrUpdate(product);
			log.debug(product.getClass().getSimpleName() + " : "
					+ product.getValues().toString());

			session.getTransaction().commit();
		} catch (Exception e) {
			session.getTransaction().rollback();
			log.error("Unable to update product.", e);
			throw e;
		}

		return rowCount;
	}

	public Shell getShell() {
		return shell;
	}
}
